import {
  downloadFile,
  getExtensionRootPath,
  loadJsxFile,
  methodEvaler,
  renderingTasks,
} from '../../core/common'
import { join } from 'path'
import { HostType } from '../../constants/common'
import { FileJson, ImportOption } from '../../types/type'
import { isHttpPath } from '../../utils/utils'
import { existsSync } from 'fs-extra'
import { Item } from './reflection/Item'

interface Result {
  code: number
  msg?: string
  data?: string
}

const _evalMethod = methodEvaler(HostType.ae)

/**
 * 引入单个文件
 * @param {string | FileJson} value
 * @returns {ProjectItem}
 */
export async function importFile (
  value: string | FileJson,
  options?: ImportOption
) {
  let filePath
  if (typeof value === 'string') {
    if (isHttpPath(value)) {
      filePath = await downloadFile(value, options?.tempFilePath)
    } else if (existsSync(value)) {
      filePath = value
    } else {
      throw new Error(`The file is not exist: ${value}`)
    }
  } else {
    // fake 处理
    filePath = ''
  }
  const projectItem = await _evalMethod('importFile', filePath)
  return projectItem
}

/**
 * 获取当前的active Item
 *
 * @export
 */
export async function getActiveItem () {
  const item = await _evalMethod('getActiveItem')
  return new Item(item)
}


/**
 * 合成当前时间线
 * 
 * @export
 * @param {number} taskId
 * @param {string} outputPath
 * @param {string} presetPath
 * @return {*} 
 */
export async function render (
  taskId: number,
  outputPath: string,
  presetPath: string
) {
  const project = await getProject()
  if (!project) {
    return new Error('project not exist')
  }
  const activeItem = await getActiveItem()
  if (!activeItem) {
    return new Error('active item not exist')
  }
  if (!existsSync(presetPath)) {
    return new Error('preset path not exist')
  }
  const jobId = await _evalMethod('render', { outputPath, presetPath })
  const task = {
    progress: 0,
    status: 'initial',
    taskId: taskId,
  }
  renderingTasks.set(jobId, task)
  return task
}

/**
 * 替换素材路径
 * @param id 素材的dynamicLinkGUID
 * @param newPath 新的素材绝对路径
 */
export async function changeMediaPath (id: string, newPath: string) {
  const fileItems = JSON.parse(await _evalMethod('getAllFootageItems'))
  const item = fileItems.find((item: any) => item.dynamicLinkGUID === id)
  if (!item) throw new Error('Not found footageItem by current ID')
  const res: Result = JSON.parse(
    await _evalMethod('replaceFile', item, encodeURIComponent(newPath))
  )
  if (res.code === 0) {
    return res.data
  } else if (res.code === 1) {
    throw new Error(res.msg)
  }
}

/**
 * 获取项目中所有合成项
 * @returns
 */
export async function getAllCompItems () {
  return JSON.parse(await _evalMethod('getAllCompItems'))
}
/**
 * 通过comp名称或者ID获取layers
 * @param value name 或者 id值
 * @param key 'name' | 'id'
 * @returns
 */
type CompKey = 'name' | 'id'
export async function getTextLayersByCompNameOrId (
  value: string,
  key: CompKey = 'name'
) {
  return JSON.parse(
    await _evalMethod('getTextLayersByCompNameOrId', value, key)
  )
}
/**
 * 获取项目中所有合成的所有的文件
 * @returns
 */
export async function getFilesOfCompItems () {
  return JSON.parse(await _evalMethod('getFilesOfCompItems'))
}
/**
 * 获取项目中所有合成的所有的文件路径
 * @returns
 */
export async function getFilePathOfCompItems () {
  try {
    const files = await getFilesOfCompItems()
    return files.map((file: any) => file?.fsName)
  } catch (err: any) {
    throw new Error(err?.message)
  }
}
/**
 * 获取项目中所有项
 * @returns
 */
export async function getAllItems () {
  return JSON.parse(await _evalMethod('getAllItems'))
}
/**
 * 获取项目中所有本地导入的素材
 * @returns
 */
export async function getAllFootageItems () {
  return JSON.parse(await _evalMethod('getAllFootageItems'))
}
/**
 * 获取当前项目
 */
export async function getProject () {
  const res = await _evalMethod('getProject')
  if (res) {
    return JSON.parse(res)
  }
  throw new Error('Project not exsit')
}

/**
 * 在目标路径下创建一个项目
 * @param targetPath 目标绝对路径
 * @returns
 */
export async function createProject (targetPath: string) {
  return _evalMethod('createProject', targetPath)
}
/**
 * 保存项目
 * @returns
 */
export async function saveProject () {
  const res = await _evalMethod('saveProject')
  if (res) {
    return res
  }
  throw new Error('Project not exsit')
}

/**
 * 初始化, 所有ae下api需要在初始化后使用
 * @export
 */
export async function init () {
  const jsxPath = join(getExtensionRootPath(), './jsx/ae')
  console.log('init jsx', jsxPath)
  await loadJsxFile(jsxPath)
  return _evalMethod('ping') // 检查是否初始化成功
}
